package com.haocjia.esdemo.highapi.index.service.impl;

import com.haocjia.esdemo.highapi.index.service.IIndexService;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.*;
import org.elasticsearch.common.settings.Settings;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class IndexService implements IIndexService {

    private final RestHighLevelClient client;


    @Override
    public CreateIndexResponse createIndex(String index) throws IOException {
        CreateIndexRequest request = indexRequest(index);
        return client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Override
    public CreateIndexResponse createIndex(String index, Map<String, Object> mapping) throws IOException {
        CreateIndexRequest request = indexRequest(index, mapping);
        return client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Override
    public CreateIndexResponse createIndex(String index, Map<String, Object> mapping, Integer shards, Integer replicas) throws IOException {
        CreateIndexRequest request = indexRequest(index, mapping, shards, replicas);
        return client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Override
    public CreateIndexResponse createIndex(String index, Integer shards, Integer replicas) throws IOException {
        CreateIndexRequest request = indexRequest(index, null, shards, replicas);
        return client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Override
    public AcknowledgedResponse deleteIndex(String index) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        return client.indices().delete(request, RequestOptions.DEFAULT);
    }

    @Override
    public Boolean exists(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest(index);
        return client.indices().exists(request, RequestOptions.DEFAULT);
    }

    @Override
    public OpenIndexResponse openIndex(String... index) throws IOException {
        OpenIndexRequest request = new OpenIndexRequest(index);
        return client.indices().open(request, RequestOptions.DEFAULT);
    }

    @Override
    public AcknowledgedResponse closeIndex(String index) throws IOException {
        CloseIndexRequest request = new CloseIndexRequest(index);
        return client.indices().close(request, RequestOptions.DEFAULT);
    }

    @Override
    public AcknowledgedResponse updateMapping(String index, Map<String, Object> mapping) throws IOException {
        PutMappingRequest request = new PutMappingRequest(index);
        request.source(mapping);
        return client.indices().putMapping(request, RequestOptions.DEFAULT);
    }

    @Override
    public IndexResponse add(String index, Object obj) {

        return null;
    }


    private CreateIndexRequest indexRequest(String index, Map<String, Object> mapping) {
        return indexRequest(index, mapping, null, null);
    }

    private CreateIndexRequest indexRequest(String index) {
        return indexRequest(index, null, null, null);
    }

    private CreateIndexRequest indexRequest(String index, Map<String, Object> mapping, Integer shards, Integer replicas) {
        CreateIndexRequest request = new CreateIndexRequest(index);
        if (mapping != null) {
            request.mapping(mapping);
        }
        if (shards != null && replicas == null) {
            request.settings(setSetting("index.number_of_shards", shards));
        }
        if (replicas != null && shards == null) {
            request.settings(setSetting("index.number_of_replicas", replicas));
        }
        if (replicas != null && shards != null) {
            request.settings(Settings.builder()
                    .put("index.number_of_shards", shards)
                    .put("index.number_of_replicas", replicas)
                    .build());
        }
        return request;
    }

    private Settings setSetting(String key, Integer val) {
        return Settings.builder()
                .put(key, val).build();
    }
}
